<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Node Types</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Node Types' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../services.html">Services</a></li><li><a href="index.html">syntax</a></li><li><a href="index.html#2">Chapter 2: The Parse Tree</a></li><li><b>Node Types</b></li></ul></div>
<p class="purpose">Each node in a syntax tree has a type, which informs whether it can have child nodes, and what in general terms it means.</p>

<ul class="toc"><li><a href="2-nt.html#SP1">&#167;1. Node types</a></li><li><a href="2-nt.html#SP3">&#167;3. Metadata on node types</a></li><li><a href="2-nt.html#SP8">&#167;8. Logging</a></li><li><a href="2-nt.html#SP9">&#167;9. Creation</a></li><li><a href="2-nt.html#SP10">&#167;10. Basic properties</a></li><li><a href="2-nt.html#SP12">&#167;12. Node types used by the syntax module</a></li><li><a href="2-nt.html#SP13">&#167;13. Parentage rules</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Node types.</b>Each node has a "node type". Some of those are defined here with <span class="extract"><span class="extract-syntax">*_NT</span></span>
names &mdash; these are the "enumerated" node types. But every <span class="extract"><span class="extract-syntax">*_MC</span></span> code,
as defined in the <a href="../words-module/index.html" class="internal">words</a> module and by its clients, is also a valid
node type. (See <a href="../words-module/2-vcb.html" class="internal">Vocabulary (in words)</a>.) The following is guaranteed to
be able to hold any node type:
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="comment-syntax"> (not a typedef because it makes trouble for </span><a href="../inweb/index.html" class="internal">inweb</a><span class="comment-syntax">)</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>In practice, then, we hold node types as unsigned integers, and we will
assume that these are at least 32 bits wide but perhaps no wider. Our
enumerated codes all have bit 32 set, and therefore no <span class="extract"><span class="extract-syntax">*_MC</span></span> can have.
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">ENUMERATED_NT_BASE</span><span class="plain-syntax"> </span><span class="constant-syntax">0x80000000</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">INVALID_NT</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax"> </span><span class="constant-syntax">0x80000000</span><span class="plain-syntax">   </span><span class="comment-syntax"> No node with this node type should ever exist</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_OVER_ENUMERATED_NTS</span><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax">=</span><span class="constant-syntax">ENUMERATED_NT_BASE</span><span class="plain-syntax">; </span><span class="identifier-syntax">t</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">ENUMERATED_NT_BASE</span><span class="plain-syntax">+</span><span class="identifier-syntax">NO_DEFINED_NT_VALUES</span><span class="plain-syntax">; </span><span class="identifier-syntax">t</span><span class="plain-syntax">++)</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">NodeType::is_enumerated</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">NodeType::is_enumerated</span></span>:<br/><a href="2-nt.html#SP7">&#167;7</a>, <a href="2-nt.html#SP9">&#167;9</a><br/>Node Annotations - <a href="2-na.html#SP15">&#167;15</a><br/>Tree Verification - <a href="2-tv.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">t</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">ENUMERATED_NT_BASE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">t</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">ENUMERATED_NT_BASE</span><span class="plain-syntax">+</span><span class="identifier-syntax">NO_DEFINED_NT_VALUES</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. Metadata on node types.</b>With what will be a profusion of node types, we need a systematic way to organise
information about them, and here it is:
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">INFTY</span><span class="plain-syntax"> </span><span class="constant-syntax">2000000000</span><span class="plain-syntax"> </span><span class="comment-syntax"> if a node has more than two billion children, we are in trouble anyway</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">node_type_metadata</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">identity</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">node_type_name</span><span class="plain-syntax">; </span><span class="comment-syntax"> name such as </span><span class="extract"><span class="extract-syntax">"HEADING_NT"</span></span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">min_children</span><span class="plain-syntax">; </span><span class="comment-syntax"> minimum legal number of child nodes</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">max_children</span><span class="plain-syntax">; </span><span class="comment-syntax"> maximum legal number of child nodes, or </span><span class="extract"><span class="extract-syntax">INFTY</span></span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">category</span><span class="plain-syntax">; </span><span class="comment-syntax"> one of the </span><span class="extract"><span class="extract-syntax">*_NCAT</span></span><span class="comment-syntax"> values below</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">node_flags</span><span class="plain-syntax">; </span><span class="comment-syntax"> bitmap of node flags</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">node_type_metadata</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure node_type_metadata is accessed in 2/tv and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>The following categories certainly exist, and <a href="../core-module/1-inaa.html" class="internal">Inform-Only Nodes and Annotations (in core)</a>
adds further ones. The idea is that <span class="extract"><span class="extract-syntax">L1_NCAT</span></span>, <span class="extract"><span class="extract-syntax">L2_NCAT</span></span> and so on down are nodes
of different "levels", with lower numbers being higher in the tree and more
structurally significant. Categories are used to decide which nodes are allowed
to be children of which others, thus enforcing this hierarchy.
</p>

<pre class="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">INVALID_NCAT</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">   </span><span class="comment-syntax"> No node with this category should ever exist</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">L1_NCAT</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">L2_NCAT</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">UNKNOWN_NCAT</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">parentage_allowed</span><span class="plain-syntax">[</span><span class="identifier-syntax">NO_DEFINED_NCAT_VALUES</span><span class="plain-syntax">][</span><span class="identifier-syntax">NO_DEFINED_NCAT_VALUES</span><span class="plain-syntax">];</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NodeType::make_parentage_allowed_table</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">NodeType::make_parentage_allowed_table</span></span>:<br/>Syntax Module - <a href="1-sm.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">NO_DEFINED_NCAT_VALUES</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">NO_DEFINED_NCAT_VALUES</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">parentage_allowed</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">][</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><a href="2-nt.html#SP5" class="function-link"><span class="function-syntax">NodeType::allow_parentage_for_categories</span></a><span class="plain-syntax">(</span><span class="constant-syntax">L1_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">L1_NCAT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">PARENTAGE_PERMISSIONS_SYNTAX_CALLBACK</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PARENTAGE_PERMISSIONS_SYNTAX_CALLBACK</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">MORE_PARENTAGE_PERMISSIONS_SYNTAX_CALLBACK</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">MORE_PARENTAGE_PERMISSIONS_SYNTAX_CALLBACK</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">EVEN_MORE_PARENTAGE_PERMISSIONS_SYNTAX_CALLBACK</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">EVEN_MORE_PARENTAGE_PERMISSIONS_SYNTAX_CALLBACK</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>The callback function <span class="extract"><span class="extract-syntax">PARENTAGE_PERMISSIONS_SYNTAX_CALLBACK</span></span> should
call this as needed to fill in more permissions:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NodeType::allow_parentage_for_categories</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">NodeType::allow_parentage_for_categories</span></span>:<br/><a href="2-nt.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">A</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">B</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">parentage_allowed</span><span class="plain-syntax">[</span><span class="identifier-syntax">A</span><span class="plain-syntax">][</span><span class="identifier-syntax">B</span><span class="plain-syntax">] = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>The bitmap of node flags currently contains only two which are used by
the syntax module, but we'll reserve two others for use by other modules:
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">DONT_VISIT_NFLAG</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000001</span><span class="plain-syntax"> </span><span class="comment-syntax"> not visited in traverses</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">TABBED_NFLAG</span><span class="plain-syntax">     </span><span class="constant-syntax">0x00000002</span><span class="plain-syntax"> </span><span class="comment-syntax"> contains tab-delimited lists</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">PHRASAL_NFLAG</span><span class="plain-syntax">    </span><span class="constant-syntax">0x00000004</span><span class="plain-syntax"> </span><span class="comment-syntax"> compiles to a function call</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">ASSERT_NFLAG</span><span class="plain-syntax">     </span><span class="constant-syntax">0x00000008</span><span class="plain-syntax"> </span><span class="comment-syntax"> allow this on either side of an assertion?</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b>And the metadata is stored in this table, whose indexes are offset by
<span class="extract"><span class="extract-syntax">ENUMERATED_NT_BASE</span></span>. We can therefore only retrieve metadata on
enumerated node types, not on meaning codes such as <span class="extract"><span class="extract-syntax">RULE_MC</span></span>, for which
the following function will return <span class="extract"><span class="extract-syntax">NULL</span></span>.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">any_node_types_created</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">node_type_created</span><span class="plain-syntax">[</span><span class="identifier-syntax">NO_DEFINED_NT_VALUES</span><span class="plain-syntax">];</span>
<span class="reserved-syntax">node_type_metadata</span><span class="plain-syntax"> </span><span class="identifier-syntax">node_type_metadatas</span><span class="plain-syntax">[</span><span class="identifier-syntax">NO_DEFINED_NT_VALUES</span><span class="plain-syntax">];</span>

<span class="reserved-syntax">node_type_metadata</span><span class="plain-syntax"> *</span><span class="function-syntax">NodeType::get_metadata</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">NodeType::get_metadata</span></span>:<br/><a href="2-nt.html#SP8">&#167;8</a>, <a href="2-nt.html#SP10">&#167;10</a>, <a href="2-nt.html#SP13">&#167;13</a><br/>Tree Verification - <a href="2-tv.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP2" class="function-link"><span class="function-syntax">NodeType::is_enumerated</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">any_node_types_created</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">node_type_created</span><span class="plain-syntax">[</span><span class="identifier-syntax">t</span><span class="plain-syntax"> - </span><span class="constant-syntax">ENUMERATED_NT_BASE</span><span class="plain-syntax">] == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">node_type_metadata</span><span class="plain-syntax"> *</span><span class="identifier-syntax">metadata</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">            &amp;(</span><span class="identifier-syntax">node_type_metadatas</span><span class="plain-syntax">[</span><span class="identifier-syntax">t</span><span class="plain-syntax"> - </span><span class="constant-syntax">ENUMERATED_NT_BASE</span><span class="plain-syntax">]);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">metadata</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">identity</span><span class="plain-syntax"> != </span><span class="identifier-syntax">t</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">, </span><span class="string-syntax">"unable to locate node type %08x\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">t</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"node type metadata lookup incorrect"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">metadata</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. Logging.</b>In the event that metadata isn't available, because the node is not
enumerated, we allow a callback function (if provided) to do the job for us.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NodeType::log</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">NodeType::log</span></span>:<br/>Syntax Module - <a href="1-sm.html#SP3">&#167;3</a><br/>Parse Nodes - <a href="2-pn.html#SP18">&#167;18</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">it</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax"> = (</span><span class="constant-syntax">node_type_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">it</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">node_type_metadata</span><span class="plain-syntax"> *</span><span class="identifier-syntax">metadata</span><span class="plain-syntax"> = </span><a href="2-nt.html#SP7" class="function-link"><span class="function-syntax">NodeType::get_metadata</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">metadata</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">metadata</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG_UNENUMERATED_NODE_TYPES_SYNTAX_CALLBACK</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOG_UNENUMERATED_NODE_TYPES_SYNTAX_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">t</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifndef</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG_UNENUMERATED_NODE_TYPES_SYNTAX_CALLBACK</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"?%08x_NT"</span><span class="plain-syntax">, </span><span class="identifier-syntax">t</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. Creation.</b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NodeType::new</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">NodeType::new</span></span>:<br/><a href="2-nt.html#SP12">&#167;12</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">identity</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">node_type_name</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">min_children</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">max_children</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">category</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">node_flags</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP2" class="function-link"><span class="function-syntax">NodeType::is_enumerated</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">identity</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"set bad metadata"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">node_type_metadata</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ptnt</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">        &amp;(</span><span class="identifier-syntax">node_type_metadatas</span><span class="plain-syntax">[</span><span class="identifier-syntax">identity</span><span class="plain-syntax"> - </span><span class="constant-syntax">ENUMERATED_NT_BASE</span><span class="plain-syntax">]);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ptnt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">identity</span><span class="plain-syntax"> = </span><span class="identifier-syntax">identity</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ptnt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">node_type_name</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ptnt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">min_children</span><span class="plain-syntax"> = </span><span class="identifier-syntax">min_children</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ptnt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">max_children</span><span class="plain-syntax"> = </span><span class="identifier-syntax">max_children</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ptnt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">category</span><span class="plain-syntax"> = </span><span class="identifier-syntax">category</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ptnt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_flags</span><span class="plain-syntax"> = </span><span class="identifier-syntax">node_flags</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">any_node_types_created</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">NO_DEFINED_NT_VALUES</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">node_type_created</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">any_node_types_created</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">node_type_created</span><span class="plain-syntax">[</span><span class="identifier-syntax">identity</span><span class="plain-syntax"> - </span><span class="constant-syntax">ENUMERATED_NT_BASE</span><span class="plain-syntax">] = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. Basic properties.</b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">NodeType::category</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">NodeType::category</span></span>:<br/>Node Annotations - <a href="2-na.html#SP14">&#167;14</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">node_type_metadata</span><span class="plain-syntax"> *</span><span class="identifier-syntax">metadata</span><span class="plain-syntax"> = </span><a href="2-nt.html#SP7" class="function-link"><span class="function-syntax">NodeType::get_metadata</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">metadata</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">metadata</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">category</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">INVALID_NCAT</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">NodeType::is_top_level</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">NodeType::is_top_level</span></span>:<br/>Syntax Trees - <a href="2-st.html#SP10">&#167;10</a>, <a href="2-st.html#SP12">&#167;12</a>, <a href="2-st.html#SP13">&#167;13</a>, <a href="2-st.html#SP14">&#167;14</a>, <a href="2-st.html#SP15">&#167;15</a>, <a href="2-st.html#SP16">&#167;16</a>, <a href="2-st.html#SP17">&#167;17</a>, <a href="2-st.html#SP18">&#167;18</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP10" class="function-link"><span class="function-syntax">NodeType::category</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">) == </span><span class="constant-syntax">L1_NCAT</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">NodeType::has_flag</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">NodeType::has_flag</span></span>:<br/>Syntax Trees - <a href="2-st.html#SP11">&#167;11</a><br/>Sentences - <a href="3-snt.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">f</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">node_type_metadata</span><span class="plain-syntax"> *</span><span class="identifier-syntax">metadata</span><span class="plain-syntax"> = </span><a href="2-nt.html#SP7" class="function-link"><span class="function-syntax">NodeType::get_metadata</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">metadata</span><span class="plain-syntax">) &amp;&amp; ((</span><span class="identifier-syntax">metadata</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_flags</span><span class="plain-syntax">) &amp; </span><span class="identifier-syntax">f</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">NodeType::get_name</span><span class="plain-syntax">(</span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">node_type_metadata</span><span class="plain-syntax"> *</span><span class="identifier-syntax">metadata</span><span class="plain-syntax"> = </span><a href="2-nt.html#SP7" class="function-link"><span class="function-syntax">NodeType::get_metadata</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">metadata</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="string-syntax">"?"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">metadata</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type_name</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>This provides a way for users of the module to indicate what's a sentence:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">NodeType::is_sentence</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">NodeType::is_sentence</span></span>:<br/>Syntax Trees - <a href="2-st.html#SP10">&#167;10</a>, <a href="2-st.html#SP12">&#167;12</a>, <a href="2-st.html#SP13">&#167;13</a>, <a href="2-st.html#SP14">&#167;14</a>, <a href="2-st.html#SP15">&#167;15</a>, <a href="2-st.html#SP16">&#167;16</a>, <a href="2-st.html#SP18">&#167;18</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">IS_SENTENCE_NODE_SYNTAX_CALLBACK</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">IS_SENTENCE_NODE_SYNTAX_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifndef</span><span class="plain-syntax"> </span><span class="identifier-syntax">IS_SENTENCE_NODE_SYNTAX_CALLBACK</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Node types used by the syntax module.</b>The <a href="index.html" class="internal">syntax</a> module uses only the following node types, but our client modules
add substantially more. The three callback functions provide opportunities to
do this. All a bit clumsy, but it works.
</p>

<pre class="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">ROOT_NT</span><span class="plain-syntax">          </span><span class="comment-syntax"> Only one such node exists per syntax tree: its root</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">INCLUSION_NT</span><span class="plain-syntax">     </span><span class="comment-syntax"> Holds a block of source material</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">HEADING_NT</span><span class="plain-syntax">       </span><span class="comment-syntax"> "Chapter VIII: Never Turn Your Back On A Shreve"</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">INCLUDE_NT</span><span class="plain-syntax">       </span><span class="comment-syntax"> "Include School Rules by Argus Filch"</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">BEGINHERE_NT</span><span class="plain-syntax">     </span><span class="comment-syntax"> "The Standard Rules begin here"</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">ENDHERE_NT</span><span class="plain-syntax">       </span><span class="comment-syntax"> "The Standard Rules end here"</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">SENTENCE_NT</span><span class="plain-syntax">      </span><span class="comment-syntax"> "The Garden is a room"</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">AMBIGUITY_NT</span><span class="plain-syntax">     </span><span class="comment-syntax"> Marks an ambiguous set of readings in the tree</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">UNKNOWN_NT</span><span class="plain-syntax">       </span><span class="comment-syntax"> "arfle barfle gloop"</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">DIALOGUE_CUE_NT</span><span class="plain-syntax">  </span><span class="comment-syntax"> A dialogue cue under a dialogue Section heading</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">DIALOGUE_CHOICE_NT</span><span class="plain-syntax"> </span><span class="comment-syntax"> A branch point in dialogue</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">DIALOGUE_LINE_NT</span><span class="plain-syntax"> </span><span class="comment-syntax"> A line of dialogue under a dialogue Section heading</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">DIALOGUE_SPEAKER_NT</span><span class="plain-syntax"> </span><span class="comment-syntax"> "James" in "James: "Hello!""</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">DIALOGUE_SPEECH_NT</span><span class="plain-syntax"> </span><span class="comment-syntax"> ""Hello!"" in "James: "Hello!""</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">DIALOGUE_SELECTION_NT</span><span class="plain-syntax"> </span><span class="comment-syntax"> "instead of examining a door"</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">DIALOGUE_CLAUSE_NT</span><span class="plain-syntax"> </span><span class="comment-syntax"> A bracketed term used in a cue or line</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NodeType::metadata_setup</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">NodeType::metadata_setup</span></span>:<br/>Syntax Module - <a href="1-sm.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><a href="2-nt.html#SP9" class="function-link"><span class="function-syntax">NodeType::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">INVALID_NT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"(INVALID_NT)"</span><span class="plain-syntax">,                     </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">INVALID_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><a href="2-nt.html#SP9" class="function-link"><span class="function-syntax">NodeType::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">ROOT_NT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"ROOT_NT"</span><span class="plain-syntax">,                             </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">L1_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">DONT_VISIT_NFLAG</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-nt.html#SP9" class="function-link"><span class="function-syntax">NodeType::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">INCLUSION_NT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"INCLUSION_NT"</span><span class="plain-syntax">,                   </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">L1_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">DONT_VISIT_NFLAG</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-nt.html#SP9" class="function-link"><span class="function-syntax">NodeType::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">HEADING_NT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"HEADING_NT"</span><span class="plain-syntax">,                       </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">L1_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-nt.html#SP9" class="function-link"><span class="function-syntax">NodeType::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">INCLUDE_NT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"INCLUDE_NT"</span><span class="plain-syntax">,                       </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">,     </span><span class="constant-syntax">L2_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-nt.html#SP9" class="function-link"><span class="function-syntax">NodeType::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">BEGINHERE_NT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"BEGINHERE_NT"</span><span class="plain-syntax">,                   </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">,     </span><span class="constant-syntax">L2_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-nt.html#SP9" class="function-link"><span class="function-syntax">NodeType::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">ENDHERE_NT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"ENDHERE_NT"</span><span class="plain-syntax">,                       </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">,     </span><span class="constant-syntax">L2_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-nt.html#SP9" class="function-link"><span class="function-syntax">NodeType::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SENTENCE_NT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"SENTENCE_NT"</span><span class="plain-syntax">,                     </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">L2_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-nt.html#SP9" class="function-link"><span class="function-syntax">NodeType::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">AMBIGUITY_NT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"AMBIGUITY_NT"</span><span class="plain-syntax">,                   </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">L1_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-nt.html#SP9" class="function-link"><span class="function-syntax">NodeType::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">UNKNOWN_NT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"UNKNOWN_NT"</span><span class="plain-syntax">,                       </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">UNKNOWN_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><a href="2-nt.html#SP9" class="function-link"><span class="function-syntax">NodeType::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DIALOGUE_CUE_NT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"DIALOGUE_CUE_NT"</span><span class="plain-syntax">,             </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">L2_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-nt.html#SP9" class="function-link"><span class="function-syntax">NodeType::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DIALOGUE_CHOICE_NT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"DIALOGUE_CHOICE_NT"</span><span class="plain-syntax">,       </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">L2_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-nt.html#SP9" class="function-link"><span class="function-syntax">NodeType::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DIALOGUE_LINE_NT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"DIALOGUE_LINE_NT"</span><span class="plain-syntax">,           </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">L2_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-nt.html#SP9" class="function-link"><span class="function-syntax">NodeType::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DIALOGUE_SPEAKER_NT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"DIALOGUE_SPEAKER_NT"</span><span class="plain-syntax">,     </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">L2_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-nt.html#SP9" class="function-link"><span class="function-syntax">NodeType::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DIALOGUE_SPEECH_NT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"DIALOGUE_SPEECH_NT"</span><span class="plain-syntax">,       </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">L2_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-nt.html#SP9" class="function-link"><span class="function-syntax">NodeType::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DIALOGUE_SELECTION_NT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"DIALOGUE_SELECTION_NT"</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">L2_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-nt.html#SP9" class="function-link"><span class="function-syntax">NodeType::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DIALOGUE_CLAUSE_NT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"DIALOGUE_CLAUSE_NT"</span><span class="plain-syntax">,       </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">L2_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">NODE_METADATA_SETUP_SYNTAX_CALLBACK</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">NODE_METADATA_SETUP_SYNTAX_CALLBACK</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">MORE_NODE_METADATA_SETUP_SYNTAX_CALLBACK</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">MORE_NODE_METADATA_SETUP_SYNTAX_CALLBACK</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">EVEN_MORE_NODE_METADATA_SETUP_SYNTAX_CALLBACK</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">EVEN_MORE_NODE_METADATA_SETUP_SYNTAX_CALLBACK</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. Parentage rules.</b>It's mostly the case that node category determines whether one node can be
parent to another, but there are exceptions.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">NodeType::parentage_allowed</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">NodeType::parentage_allowed</span></span>:<br/>Tree Verification - <a href="2-tv.html#SP4_3">&#167;4.3</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">t_parent</span><span class="plain-syntax">, </span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">t_child</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">node_type_metadata</span><span class="plain-syntax"> *</span><span class="identifier-syntax">metadata_parent</span><span class="plain-syntax"> = </span><a href="2-nt.html#SP7" class="function-link"><span class="function-syntax">NodeType::get_metadata</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t_parent</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">metadata_parent</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">node_type_metadata</span><span class="plain-syntax"> *</span><span class="identifier-syntax">metadata_child</span><span class="plain-syntax"> = </span><a href="2-nt.html#SP7" class="function-link"><span class="function-syntax">NodeType::get_metadata</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t_child</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">metadata_child</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cat_child</span><span class="plain-syntax"> = </span><span class="identifier-syntax">metadata_child</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">category</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cat_parent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">metadata_parent</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">category</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parentage_allowed</span><span class="plain-syntax">[</span><span class="identifier-syntax">cat_parent</span><span class="plain-syntax">][</span><span class="identifier-syntax">cat_child</span><span class="plain-syntax">]) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">t_parent</span><span class="plain-syntax"> == </span><span class="constant-syntax">HEADING_NT</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">cat_child</span><span class="plain-syntax"> == </span><span class="constant-syntax">L2_NCAT</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">t_parent</span><span class="plain-syntax"> == </span><span class="constant-syntax">DIALOGUE_LINE_NT</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        ((</span><span class="identifier-syntax">t_child</span><span class="plain-syntax"> == </span><span class="constant-syntax">DIALOGUE_SPEAKER_NT</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">t_child</span><span class="plain-syntax"> == </span><span class="constant-syntax">DIALOGUE_SPEECH_NT</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">t_child</span><span class="plain-syntax"> == </span><span class="constant-syntax">DIALOGUE_CLAUSE_NT</span><span class="plain-syntax">)))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">t_parent</span><span class="plain-syntax"> == </span><span class="constant-syntax">DIALOGUE_CUE_NT</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">t_child</span><span class="plain-syntax"> == </span><span class="constant-syntax">DIALOGUE_CLAUSE_NT</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">t_parent</span><span class="plain-syntax"> == </span><span class="constant-syntax">DIALOGUE_CHOICE_NT</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        ((</span><span class="identifier-syntax">t_child</span><span class="plain-syntax"> == </span><span class="constant-syntax">DIALOGUE_CLAUSE_NT</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">t_child</span><span class="plain-syntax"> == </span><span class="constant-syntax">DIALOGUE_SELECTION_NT</span><span class="plain-syntax">)))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">PARENTAGE_EXCEPTIONS_SYNTAX_CALLBACK</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PARENTAGE_EXCEPTIONS_SYNTAX_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">t_parent</span><span class="plain-syntax">, </span><span class="identifier-syntax">cat_parent</span><span class="plain-syntax">, </span><span class="identifier-syntax">t_child</span><span class="plain-syntax">, </span><span class="identifier-syntax">cat_child</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">t_parent</span><span class="plain-syntax"> == </span><span class="constant-syntax">AMBIGUITY_NT</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">t_child</span><span class="plain-syntax"> == </span><span class="constant-syntax">AMBIGUITY_NT</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="2-st.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-sm.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-st.html">st</a></li><li class="progresscurrent">nt</li><li class="progresssection"><a href="2-pn.html">pn</a></li><li class="progresssection"><a href="2-na.html">na</a></li><li class="progresssection"><a href="2-tv.html">tv</a></li><li class="progresssection"><a href="2-spc.html">spc</a></li><li class="progresschapter"><a href="3-snt.html">3</a></li><li class="progressnext"><a href="2-pn.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

